<template>
  <uploader ref="uploader" :options="options" :file-status-text="statusText" class="uploader-example"
            @file-complete="fileComplete"
            @file-added="onFileAdded"
            @complete="complete" @file-success="onFileSuccess">
    <uploader-unsupport></uploader-unsupport>
    <uploader-drop>
      <p>Drop files here to upload or</p>
      <uploader-btn>select files</uploader-btn>
      <uploader-btn :attrs="attrs">select images</uploader-btn>
      <uploader-btn :directory="true">select folder</uploader-btn>
    </uploader-drop>
    <uploader-list ref="uploaderList"></uploader-list>
  </uploader>
</template>

<script>

import store from '@/store'
import uploaderList from '@/components/uploader/list'
import SparkMD5 from 'spark-md5'
import { axiosBaseUrl } from '@/common/config/baseConfig'

export default {
  components: {
    uploaderList
  },
  props: {
    uploadUrl: {
      type: String,
      default: '/api/v1/attachment/multipartUpload'
    },
    uploadPath: {
      type: String,
      default: 'ATTACHMENT'
    }
  },
  data () {
    return {
      options: {},
      attrs: {
        accept: 'image/*'
      },
      statusText: {
        success: '上传成功',
        error:
          '上传失败',
        uploading:
          '上传中',
        paused:
          '暂停中',
        processing:
          '处理中',
        waiting:
          '等待中'
      }
    }
  },

  methods: {
    initUploader () {
      this.options = {
        target: axiosBaseUrl + this.uploadUrl,
        chunkSize: 5 * 1024 * 1024,
        fileParameterName: 'file', // 上传文件时文件的参数名，默认file
        maxChunkRetries: 3, // 最大自动失败重试上传次数
        testChunks: true, // 是否开启服务器分片校验
        query: { path: this.uploadPath },
        // 服务器分片校验函数，秒传及断点续传基础
        checkChunkUploadedByResponse: function (chunk, message) {
          const objMessage = JSON.parse(message)
          if (objMessage.code === 10000 && objMessage.msg === '该文件已存在') {
            return true
          }
          return (objMessage.data || []).indexOf(chunk.offset + 1) >= 0
        },
        headers: {
          // 在header中添加的验证，请根据实际业务来
          authorization: store.getters.token
        }
      }
    },
    onFileAdded (file) {
      const fileReader = new FileReader()
      const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
      let currentChunk = 0
      const chunkSize = 10 * 1024 * 1000
      const chunks = Math.ceil(file.size / chunkSize)
      const spark = new SparkMD5.ArrayBuffer()
      file.pause()
      file.isProcessing = true
      loadNext()
      fileReader.onload = e => {
        spark.append(e.target.result)
        if (currentChunk < chunks) {
          currentChunk++
          loadNext()
        } else {
          const md5 = spark.end()
          this.computeMD5Success(md5, file)
        }
      }
      fileReader.onerror = function () {
        file.cancel()
      }

      function loadNext () {
        const start = currentChunk * chunkSize
        const end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize
        fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end))
      }
    },
    computeMD5Success (md5, file) {
      file.uniqueIdentifier = md5
      file.resume()
      file.isProcessing = false
    },
    // 上传完成
    complete () {
    },
    // 一个根文件（文件夹）成功上传完成。
    fileComplete () {
    },
    onFileSuccess (rootFile, file, response, chunk) {
    }
  },
  computed: {
    // Uploader实例
    uploader () {
      return this.$refs.uploader.uploader
    }
  },
  created () {
    this.initUploader()
  }
}

</script>

<style scoped>
.uploader-example {
  width: 880px;
  padding: 15px;
  margin: 40px auto 0;
  font-size: 12px;
  box-shadow: 0 0 10px rgba(0, 0, 0, .4);
}

.uploader-example .uploader-btn {
  margin-right: 4px;
}

.uploader-example .uploader-list {
  max-height: 440px;
  overflow: auto;
  overflow-x: hidden;
  overflow-y: auto;
}
</style>
